package cn.wolfcode.business.service.impl;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.wolfcode.business.domain.BpmnInfo;
import cn.wolfcode.business.domain.ServiceItem;
import cn.wolfcode.business.mapper.BpmnInfoMapper;
import cn.wolfcode.business.mapper.ServiceItemMapper;
import cn.wolfcode.business.vo.FlowAuditVO;
import cn.wolfcode.business.vo.HistoryVO;
import cn.wolfcode.common.exception.ServiceException;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.PageUtils;
import cn.wolfcode.common.utils.SecurityUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.CarPackageAuditMapper;
import cn.wolfcode.business.domain.CarPackageAudit;
import cn.wolfcode.business.service.ICarPackageAuditService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 套餐审核Service业务层处理
 * 
 * @author dafei
 * @date 2024-03-07
 */
@Service
@Transactional
public class CarPackageAuditServiceImpl implements ICarPackageAuditService 
{
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private ServiceItemMapper serviceItemMapper;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;
    /**
     * 查询套餐审核
     * 
     * @param id 套餐审核主键
     * @return 套餐审核
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询套餐审核列表
     * 
     * @param carPackageAudit 套餐审核
     * @return 套餐审核
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
    }

    /**
     * 新增套餐审核
     * 
     * @param carPackageAudit 套餐审核
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改套餐审核
     * 
     * @param carPackageAudit 套餐审核
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 批量删除套餐审核
     * 
     * @param ids 需要删除的套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(Long[] ids)
    {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(ids);
    }

    /**
     * 删除套餐审核信息
     * 
     * @param id 套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }

    @Override
    public InputStream getProcessResource(Long id) {

        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(id);

        if(audit == null){
            throw new ServiceException("参数异常");
        }

        BpmnInfo bpmnInfo = bpmnInfoMapper.selectByType(CarPackageAudit.FLOW_AUDIT_TYPE);
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(bpmnInfo.getVersion())
                .singleResult();

        DefaultProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
        List<String> activeActivityIds = Collections.emptyList();

        //当流程还在审核中
        if(audit.getStatus() == CarPackageAudit.STATUS_IN_ROGRESS){
            activeActivityIds = runtimeService.getActiveActivityIds(audit.getInstanceId());
        }
        /**
         * 第一个参数: 流程定义模型
         * 第二个参数: 高亮节点集合
         * 第三个参数: 高亮连线集合
         */
        return processDiagramGenerator.generateDiagram(bpmnModel,
                activeActivityIds,   //高亮显示当前流程到哪个节点
                Collections.emptyList(),   //高亮显示流程线
                "宋体",
                "宋体",
                "宋体");

    }

    @Override
    public void cancelAudit(Long id) {

        //条件
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(id);
        if(audit == null){
            throw new ServiceException("参数异常");
        }
        if(audit.getStatus() != CarPackageAudit.STATUS_IN_ROGRESS){
            throw new ServiceException("只有在审核中状态才允许撤销");
        }

        //改数据
        //服务套餐审核状态--初始化
        //serviceItemMapper.updateAuditStatus(id, ServiceItem.AUDITSTATUS_INIT);
        ServiceItem serviceItem = serviceItemMapper.selectServiceItemById(audit.getServiceItemId());
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        serviceItemMapper.updateServiceItem(serviceItem);

        //套餐审核记录信息状态--审核撤销
        audit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAuditMapper.updateCarPackageAudit(audit);

        // 审核流程实例--删除
        runtimeService.deleteProcessInstance(audit.getInstanceId(), "审核数据有问题");

    }

    @Override
    public List<HistoryVO> auditHistory(Long id) {
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(id);
        if(audit == null){
            throw new ServiceException("参数异常");
        }
        //通过实例id查询该实例下所有的task任务历史（审核历史）
        List<HistoricTaskInstance> taskHistoryList = historyService
                .createHistoricTaskInstanceQuery()
                .processInstanceId(audit.getInstanceId())
                .list();

        List<HistoryVO>  list = new ArrayList<>();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        if(taskHistoryList != null && taskHistoryList.size() > 0){
            for (HistoricTaskInstance hs : taskHistoryList) {
                HistoryVO vo = new HistoryVO();
                vo.setTaskName(hs.getName());
                vo.setStartTime(format.format(hs.getStartTime()));
                if(hs.getEndTime() != null){
                    vo.setEndTime(format.format(hs.getEndTime()));
                }
                if(hs.getDurationInMillis() != null){
                    vo.setDurationInMillis(hs.getDurationInMillis()/1000+"s");
                }
                //审核信息-备注
                List<Comment> commentList = taskService.getTaskComments(hs.getId());
                if(commentList!= null && commentList.size() > 0){
                    vo.setComment(commentList.get(0).getFullMessage());
                }
                list.add(vo);
            }
        }
        return list;
    }

    @Override
    public List<CarPackageAudit> selectListForTodo(CarPackageAudit carPackageAudit) {

        BpmnInfo bpmnInfo = bpmnInfoMapper.selectByType(CarPackageAudit.FLOW_AUDIT_TYPE);

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())  //服务套餐
                .taskAssignee(SecurityUtils.getUserId().toString())
                .list();


        List<String> instanceIds = new ArrayList<>();

        if(list != null && list.size() > 0){
            for (Task task : list) {
                instanceIds.add(task.getProcessInstanceId());
            }
        }else{
            return new ArrayList<CarPackageAudit>();
        }

        PageUtils.startPage();
        return carPackageAuditMapper.selectByInstanceIds(instanceIds);
    }

    @Override
    public void audit(FlowAuditVO vo) {

        //条件
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(vo.getId());

        if(audit == null){
            throw new ServiceException("参数异常");
        }

        if(audit.getStatus() != CarPackageAudit.STATUS_IN_ROGRESS){
            throw new ServiceException("必须是审核中状态才允许审核");
        }

        //改数据
        //流程线--处理节点
        Task task = taskService.createTaskQuery()
                .taskAssignee(SecurityUtils.getUserId().toString())
                .processInstanceId(audit.getInstanceId())
                .singleResult();

        if(task == null){
            return;
        }
        //备注
        String message = "";
        if(vo.getStatus() == CarPackageAudit.STATUS_PASS){
            message = "审批人" + SecurityUtils.getUsername() + "同意-审批意见[" + vo.getInfo() +"]";
        }else{
            message = "审批人" + SecurityUtils.getUsername() + "拒绝-审批意见[" + vo.getInfo() +"]";
        }
        taskService.addComment(task.getId(), audit.getInstanceId(), message);

        //审核通过/拒绝--控制变量
        Map<String, Object> map =new HashMap<>();
        map.put("shopOwner", vo.getStatus() == CarPackageAudit.STATUS_PASS);
        //执行
        taskService.complete(task.getId(), map);

        //下一个节点
        Task nextTask = taskService.createTaskQuery()
                .processInstanceId(audit.getInstanceId())
                .singleResult();
        //业务线
        if(vo.getStatus() == CarPackageAudit.STATUS_PASS){
            //1：审核通过--改数据
            //  --判断是否有下一个(审核)节点
            if(nextTask == null){
                //     --无
                //         审核信息记录表状态：审核通过
                audit.setStatus(CarPackageAudit.STATUS_PASS);
                carPackageAuditMapper.updateCarPackageAudit(audit);
                //         服务项状态：通过
                ServiceItem serviceItem = serviceItemMapper.selectServiceItemById(audit.getServiceItemId());
                serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
                serviceItemMapper.updateServiceItem(serviceItem);
            }
            //     --有 啥都不用做
        }else if(vo.getStatus() == CarPackageAudit.STATUS_REJECT){
            //2：审核拒绝--改数据
            //   审核信息记录表状态：审核拒绝
            audit.setStatus(CarPackageAudit.STATUS_REJECT);
            carPackageAuditMapper.updateCarPackageAudit(audit);
            //   服务项状态：初始化
            ServiceItem serviceItem = serviceItemMapper.selectServiceItemById(audit.getServiceItemId());
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
            serviceItemMapper.updateServiceItem(serviceItem);
        }

    }

    @Override
    public List<CarPackageAudit> selectListForDone(CarPackageAudit carPackageAudit) {
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectByType(CarPackageAudit.FLOW_AUDIT_TYPE);

 /*       List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())  //服务套餐
                .taskAssignee(SecurityUtils.getUserId().toString())
                .list();*/

        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(SecurityUtils.getUserId().toString())
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())
                .list();


        List<String> instanceIds = new ArrayList<>();

        if(list != null && list.size() > 0){
            for (HistoricTaskInstance task : list) {
                instanceIds.add(task.getProcessInstanceId());
            }
        }else{
            return new ArrayList<CarPackageAudit>();
        }

        PageUtils.startPage();
        return carPackageAuditMapper.selectByInstanceIds(instanceIds);
    }
}
